From 68d8221103c2e6886cfceddb0f80f49fdf976622 Mon Sep 17 00:00:00 2001 From: Alex Williamson Date: Tue, 20 Nov 2007 09:11:15 -0700 Subject: [PATCH] [IA64] vti save-restore: fix opt_feature hypercall - Fix XEN_IA64_OPTF_IDENT_MAP_REG[457] definitions. - SMP fix. writing to domain->arch.opt_feature is racy. Signed-off-by: Isaku Yamahata --- xen/arch/ia64/xen/domain.c | 20 ++++++++++++++++++-- xen/include/asm-ia64/domain.h | 10 ++++++++-- xen/include/public/arch-ia64.h | 4 +++- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c index 47924a54e0..d951cca218 100644 --- a/xen/arch/ia64/xen/domain.c +++ b/xen/arch/ia64/xen/domain.c @@ -2285,13 +2285,23 @@ optf_set_identity_mapping(unsigned long* mask, struct identity_mapping* im, } } -/* Switch a optimization feature on/off. */ +/* + * Switch an optimization feature on/off. + * The vcpu must be paused to avoid racy access to opt_feature. + */ int domain_opt_feature(struct xen_ia64_opt_feature* f) { - struct opt_feature* optf = &(current->domain->arch.opt_feature); + struct domain *d = current->domain; + struct opt_feature* optf = &d->arch.opt_feature; + struct vcpu *v; long rc = 0; + for_each_vcpu(d, v) { + if (v != current) + vcpu_pause(v); + } + switch (f->cmd) { case XEN_IA64_OPTF_IDENT_MAP_REG4: optf_set_identity_mapping(&optf->mask, &optf->im_reg4, f); @@ -2307,6 +2317,12 @@ domain_opt_feature(struct xen_ia64_opt_feature* f) rc = -ENOSYS; break; } + + for_each_vcpu(d, v) { + if (v != current) + vcpu_unpause(v); + } + return rc; } diff --git a/xen/include/asm-ia64/domain.h b/xen/include/asm-ia64/domain.h index 91d4d9f709..486696d679 100644 --- a/xen/include/asm-ia64/domain.h +++ b/xen/include/asm-ia64/domain.h @@ -105,9 +105,15 @@ struct opt_feature { * The base XEN_IA64_OPTF_IDENT_MAP_REG7 is defined in public/arch-ia64.h. * Identity mapping of region 4 addresses in HVM. */ -#define XEN_IA64_OPTF_IDENT_MAP_REG4 (XEN_IA64_OPTF_IDENT_MAP_REG7 + 1) +#define XEN_IA64_OPTF_IDENT_MAP_REG4_BIT \ + (XEN_IA64_OPTF_IDENT_MAP_REG7_BIT + 1) +#define XEN_IA64_OPTF_IDENT_MAP_REG4 \ + (1UL << XEN_IA64_OPTF_IDENT_MAP_REG4_BIT) /* Identity mapping of region 5 addresses in HVM. */ -#define XEN_IA64_OPTF_IDENT_MAP_REG5 (XEN_IA64_OPTF_IDENT_MAP_REG4 + 1) +#define XEN_IA64_OPTF_IDENT_MAP_REG5_BIT \ + (XEN_IA64_OPTF_IDENT_MAP_REG7_BIT + 2) +#define XEN_IA64_OPTF_IDENT_MAP_REG5 \ + (1UL << XEN_IA64_OPTF_IDENT_MAP_REG5_BIT) /* Set an optimization feature in the struct arch_domain. */ extern int domain_opt_feature(struct xen_ia64_opt_feature*); diff --git a/xen/include/public/arch-ia64.h b/xen/include/public/arch-ia64.h index d197a79bfa..0895dd0eff 100644 --- a/xen/include/public/arch-ia64.h +++ b/xen/include/public/arch-ia64.h @@ -674,7 +674,9 @@ DEFINE_XEN_GUEST_HANDLE(xen_ia64_debug_op_t); * This is useful in guests using region 7 for identity mapping * like the linux kernel does. */ -#define XEN_IA64_OPTF_IDENT_MAP_REG7 0x1UL +#define XEN_IA64_OPTF_IDENT_MAP_REG7_BIT 0 +#define XEN_IA64_OPTF_IDENT_MAP_REG7 \ + (1UL << XEN_IA64_OPTF_IDENT_MAP_REG7_BIT) struct xen_ia64_opt_feature { unsigned long cmd; /* Which feature */ -- 2.30.2